#include <cstdio>
#include <cstdarg>
#include <cstdlib>
#include <iostream>

using namespace std;

#define LOG(fmt, ...) printf("[%s:%d]" fmt, __FILE__, __LINE__, ##__VA_ARGS__);

void printNum(int count, ...){
    va_list ap;
    //获取指定参数的起始地址（count之后的第一个参数）
    va_start(ap, count);
    for (int i = 0; i < count;i++){
        //从ap中获取指定类型的数据，存放到num中
        int num = va_arg(ap, int);
        printf("param[%d]:%d\n", i, num);
    }
    //将ap指针置空
    va_end(ap);
}

void myprintf(const char* format, ...){
    va_list(ap);
    va_start(ap, format);
    char *buf;
    //int vasprintf(char **strp, const char *fmt, va_list ap);
    //成功返回获取的字符串的长度，失败返回-1，buf需要手动释放
    int ret = vasprintf(&buf, format, ap);
    if(ret != -1){
        printf(buf);
        free(buf);
    }
    va_end(ap);
}
// int main(){

//     LOG("%s-%d\n", "xxxx", 666);
//     printNum(2, 666, 777);
//     myprintf("%s-%d\n", "xxxx", 666);
//     return 0;
// }

//特化参数为空
void xprintf(){
    cout << endl;
}
template<class T, class ...Args>
void xprintf(const T &v, Args &&...args){
    cout << v;
    //这里虽然在运行的时候会分支，但编译的时候不会
    //即使是(sizeof ...(args))==0，也会递归编译xprintf(forward<Args>(args)...);，这样就导致必须要写xprintf的空特化，不然编译就会报错
    if((sizeof ...(args))>0){
        cout << "[" <<sizeof...(args) << "]";
        xprintf(forward<Args>(args)...);
    }else{
        xprintf();
    }
}

int main(){
    xprintf("xx1");
    xprintf("xx1", "xx2");
    xprintf("xx1", "xx2", 666);
    return 0;
}